package com.chenfan.mcn.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chenfan.mcn.clients.baseinfo.BaseCustomer;
import com.chenfan.mcn.clients.baseinfo.BaseInfoClient;
import com.chenfan.mcn.clients.baseinfo.DescByCodeDTO;
import com.chenfan.mcn.clients.privilege.PrivilegeClient;
import com.chenfan.mcn.clients.privilege.SUser;
import com.chenfan.mcn.constant.NumberCst;
import com.chenfan.mcn.dao.LiveContractCommodityMapper;
import com.chenfan.mcn.dao.LiveSettlementCommodityMapper;
import com.chenfan.mcn.dao.StarPlatformInfoMapper;
import com.chenfan.common.extension.dict.DictStream;
import com.chenfan.common.extension.dict.DictTranslationUtils;
import com.chenfan.mcn.extension.excel.ExcelUtils;
import com.chenfan.mcn.model.LiveSettlementCommodity;
import com.chenfan.mcn.model.StarPlatformInfo;
import com.chenfan.mcn.model.dto.LiveSettlementCommodityDto;
import com.chenfan.mcn.model.vo.*;
import com.chenfan.mcn.service.BrandInfoService;
import com.chenfan.mcn.service.LiveSettlementCommodityService;
import com.chenfan.mcn.utils.CommonUtil;
import com.chenfan.mcn.utils.ExcelUtilWithEasyExcel;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author liuming
 * @date 2023-04-27 11:01
 */
@Service
@Slf4j
public class LiveSettlementCommodityServiceImpl implements LiveSettlementCommodityService {

    @Autowired
    private StarPlatformInfoMapper starPlatformInfoMapper;

    @Autowired
    private LiveContractCommodityMapper liveContractCommodityMapper;
    
    @Autowired
    private LiveSettlementCommodityMapper lscMapper;

    @Autowired
    private PrivilegeClient privilegeClient;

    @Autowired
    private BaseInfoClient baseInfoClient;

    @Autowired
    private BrandInfoService brandInfoService;


    @Override
    public void exportExcel(LiveSettlementCommodityDto dto, HttpServletResponse response) {
        dto.setPageNum(1);
        dto.setPageSize(Integer.MAX_VALUE);
        List<LiveContractCommodityVo> list = page(dto).getRecords();
        Map<Long, LiveSettlementCommodity> settlementCommoditieMap = CommonUtil.getIfNecessary(CollectionUtils.isNotEmpty(list), () -> {
            Set<Long> lccIds = list.stream().map(x -> x.getLccId()).collect(Collectors.toSet());
            List<LiveSettlementCommodity> settlementCommodities = lscMapper.getListByLccIds(lccIds);
            return settlementCommodities.stream().collect(Collectors.toMap(LiveSettlementCommodity::getLccId, x -> x, (x, y) -> x));
        }, Collections.EMPTY_MAP);
        List<String> brandCodes = list.stream().map(LiveContractCommodityVo::getCooperateBrand).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<String,String> brandMap = brandInfoService.getBrandMapByCodes(brandCodes);
        List<Long> franchiserIds = list.stream().map(LiveContractCommodityVo::getFranchiserId).collect(Collectors.toList());
        List<Long> customerIds = list.stream().map(LiveContractCommodityVo::getCustomerId).collect(Collectors.toList());
        Map<Long, SUser> userMap = privilegeClient.getUserByIds(franchiserIds).getObj().stream().collect(Collectors.toMap(SUser::getUserId, Function.identity(), (a, b) -> a));
        Map<Long, BaseCustomer> customerMap = baseInfoClient.getMcnCustomerByIds(customerIds).getObj();
        list.stream().forEach(vo -> {
            if(brandMap.containsKey(vo.getCooperateBrand())) {
                vo.setCooperateBrand(brandMap.get(vo.getCooperateBrand()));
            }
            LiveSettlementCommodity liveSettlementCommodity = settlementCommoditieMap.get(vo.getLccId());
            if (Objects.nonNull(liveSettlementCommodity)) {
                vo.setShopName(liveSettlementCommodity.getShopName());
                vo.setCommissionRate(liveSettlementCommodity.getCommissionRate());
            }

            if (Objects.nonNull(vo.getFranchiserId())) {
                SUser sUser = userMap.get(vo.getFranchiserId());
                if (Objects.nonNull(sUser)) {
                    vo.setFranchiserName(sUser.getUsername());
                }
            }
            if (Objects.nonNull(vo.getCustomerId())) {
                BaseCustomer baseCustomer = CommonUtil.getMapValue(customerMap, vo.getCustomerId());
                vo.setCustomerName(Objects.nonNull(baseCustomer) ? baseCustomer.getCustomerNameC() : null);
            }
            BigDecimal commissionRate = Objects.isNull(vo.getCommissionRate()) ? BigDecimal.ZERO : vo.getCommissionRate();
            BigDecimal clickRate = Objects.isNull(vo.getClickRate()) ? BigDecimal.ZERO : vo.getClickRate();
            BigDecimal beforeRefundRate = Objects.isNull(vo.getBeforeRefundRate()) ? BigDecimal.ZERO : vo.getBeforeRefundRate();
            BigDecimal afterRefundRate = Objects.isNull(vo.getAfterRefundRate()) ? BigDecimal.ZERO : vo.getAfterRefundRate();
            BigDecimal tradeTransfRate = Objects.isNull(vo.getTradeTransfRate()) ? BigDecimal.ZERO : vo.getTradeTransfRate();
            vo.setCommissionRate(commissionRate.multiply(BigDecimal.valueOf(100L)).setScale(2, BigDecimal.ROUND_HALF_UP));
            vo.setCommissionRateStr(vo.getCommissionRate() + "%");
            vo.setClickRateStr(clickRate+"%");
            vo.setBeforeRefundRateStr(beforeRefundRate+ "%");
            vo.setAfterRefundRateStr(afterRefundRate + "%");
            vo.setTradeTransfRateStr(tradeTransfRate+"%");
        });
        DictTranslationUtils.translation(() -> DictStream.of(
                     DictStream.map("liveContractCategory", LiveContractCommodityVo::getLiveContractCategory, LiveContractCommodityVo::setLiveContractCategoryName)),
                     (dictProfileList, dictList) -> Objects.requireNonNull(baseInfoClient.getDescByCode(new DescByCodeDTO().setDictsCodes(dictList).setProfileCodes(dictProfileList))).getObj(),
                     list
             );
        StringBuilder filename = new StringBuilder("直播商品导出").append(DateUtil.format(new Date(), "yyyy-MM-dd")).append(".xlsx");
        ExcelUtils.exportExcel(list, "直播商品导出", LiveContractCommodityVo.class, filename.toString(), response);
    }

    @Override
    public void exportSettlementExcel(LiveSettlementCommodityDto dto, HttpServletResponse response) {
        //根据条件获取结算商品数据
        Page<LiveSettlementCommodityExportVo> data = lscMapper.settlementExportDataByCondition(new Page<LiveContractCommodityVo>(1, Integer.MAX_VALUE), dto);
        List<LiveSettlementCommodityExportVo> records = data.getRecords();

        String name = "结算商品导出";
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd+HH_mm_ss");
        String localDateTimeStr = df.format(LocalDateTime.now());
        String fileName = name + localDateTimeStr + ".xlsx";
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (CollUtil.isNotEmpty(records)) {
            for (LiveSettlementCommodityExportVo vo : records) {
                if (Objects.equals(vo.getSettlementStatus(), NumberCst.ZERO)) {
                    vo.setSettlementStatusStr("待结算");
                } else if (Objects.equals(vo.getSettlementStatus(), NumberCst.ONE)) {
                    vo.setSettlementStatusStr("结算中");
                } else if (Objects.equals(vo.getSettlementStatus(), NumberCst.TWO)) {
                    vo.setSettlementStatusStr("已结算");
                } else {
                    vo.setSettlementStatusStr("状态未定义");
                }
                vo.setCommissionRate(Objects.isNull(vo.getCommissionRate()) ? BigDecimal.ZERO : vo.getCommissionRate());
                vo.setCommissionRateStr(vo.getCommissionRate().multiply(BigDecimal.valueOf(100L)).setScale(2, BigDecimal.ROUND_HALF_UP) + "%");
                vo.setCreateDateStr(vo.getCreateDate().format(fmt));
            }
            ExcelUtilWithEasyExcel.exportExcelByEasyExcel(records, name, name, LiveSettlementCommodityExportVo.class, fileName, response);
        } else {
            ExcelUtilWithEasyExcel.exportExcelByEasyExcel(new ArrayList<>(), name, name, LiveSettlementCommodityExportVo.class, fileName, response);

        }
    }

    @Override
    public Page<LiveSettlementCommodityExportVo> pageV2(LiveSettlementCommodityDto dto) {

        Page<LiveSettlementCommodityExportVo> page = lscMapper.settlementExportDataByCondition(new Page<LiveContractCommodityVo>(dto.getPageNum(), dto.getPageSize()), dto);
        //查询主播
        Set<Long> starPlatIds = page.getRecords().stream().map(x -> x.getStarPlatId()).collect(Collectors.toSet());
        List<StarPlatInfoVO> starPlatInfoVos = starPlatformInfoMapper.getByIds(new ArrayList<>(starPlatIds));
        Map<Long, StarPlatInfoVO> starPlatInfoVoMap = starPlatInfoVos.stream().collect(Collectors.toMap(x -> x.getId(), x -> x, (x, y) -> x));
        page.getRecords().stream().forEach(entity -> {
            StarPlatInfoVO starPlatInfoVo = starPlatInfoVoMap.get(entity.getStarPlatId());
            if (Objects.nonNull(starPlatInfoVo)) {
                entity.setAnchorName(starPlatInfoVo.getPlatNickName());
                entity.setLivePlatformName(starPlatInfoVo.getPlatformName());
            }
            if (Objects.nonNull(entity.getCommissionRate())) {
                entity.setCommissionRate(entity.getCommissionRate().multiply(BigDecimal.valueOf(100L)));
            }
        });
        return page;
    }

    @Override
    public Page<LiveContractCommodityVo> page(LiveSettlementCommodityDto dto) {
        Page<LiveContractCommodityVo> page = lscMapper.page(new Page<>(dto.getPageNum(), dto.getPageSize()), dto);
        //查询主播
        Set<Long> starPlatIds = page.getRecords().stream().map(x -> x.getStarPlatId()).collect(Collectors.toSet());
        List<StarPlatInfoVO> starPlatInfoVos = starPlatformInfoMapper.getByIds(new ArrayList<>(starPlatIds));
        Map<Long, StarPlatInfoVO> starPlatInfoVoMap = starPlatInfoVos.stream().collect(Collectors.toMap(x -> x.getId(), x -> x, (x, y) -> x));
        page.getRecords().stream().forEach(entity -> {
            StarPlatInfoVO starPlatInfoVo = starPlatInfoVoMap.get(entity.getStarPlatId());
            if (Objects.nonNull(starPlatInfoVo)) {
                entity.setAnchorName(starPlatInfoVo.getPlatNickName());
                entity.setLivePlatformName(starPlatInfoVo.getPlatformName());
            }
        });
        return page;
    }

    @Override
    public LiveContractCommodityVo detail(Long lccId) {
        if (Objects.isNull(lccId)) {
            return null;
        }
        LiveContractCommodityVo liveContractCommodityVo = liveContractCommodityMapper.detail(lccId);

        //查询招商信息
        if (Objects.nonNull(liveContractCommodityVo.getFranchiserId())) {
            Map<Long, String> franchiserMap = CommonUtil.defaultList(privilegeClient.getUserByIds(Lists.newArrayList(liveContractCommodityVo.getFranchiserId())).getObj()).stream().collect(Collectors.toMap(k -> k.getUserId(), v -> v.getUsername()));
            liveContractCommodityVo.setFranchiserName(franchiserMap.get(liveContractCommodityVo.getFranchiserId()));
        }

        //查询红人平台信息
        if (Objects.nonNull(liveContractCommodityVo.getStarPlatId())) {
            StarPlatformInfo starPlatformInfo = starPlatformInfoMapper.selectById(liveContractCommodityVo.getStarPlatId());
            liveContractCommodityVo.setAnchorName(starPlatformInfo.getPlatNickName());
            liveContractCommodityVo.setLivePlatformName(starPlatformInfo.getPlatformName());
        }

        DictTranslationUtils.translation(() -> DictStream.of(
                DictStream.map("liveContractCategory", LiveContractCommodityVo::getLiveContractCategory, LiveContractCommodityVo::setLiveContractCategoryName)
                ),
                (dictProfileList, dictList) -> Objects.requireNonNull(baseInfoClient.getDescByCode(new DescByCodeDTO()
                        .setDictsCodes(dictList.stream().distinct().collect(Collectors.toList())).setProfileCodes(dictProfileList))).getObj(),
                liveContractCommodityVo
        );


        //查询结算商品列表
        List<LiveSettlementCommodityDataVo> dataVos = lscMapper.getDetailByLccId(lccId);
        liveContractCommodityVo.setDataVos(dataVos);
        return liveContractCommodityVo;
    }


}
